<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\User; // 引入了 App\Models\User 用户模型

use App\Http\Requests\UserRequest; // 引入 UserRequest

use App\Handlers\ImageUploadHandler;

class UsersController extends Controller
{

    /**
     * __construct 是 PHP 的构造器方法，当一个类对象被创建之前该方法将会被调用.
     * 我们在 __construct 方法中调用了 middleware 方法，
     * 该方法接收两个参数，第一个为中间件的名称，第二个为要进行过滤的动作
     * 在控制器 Auth 中间件使用中，首选 except 方法，
     * 这样的话，当你新增一个控制器方法时，默认是安全的，此为最佳实践
     */
    public function __construct()
    {
        $this->middleware('auth', ['except' => ['show']]);
    }

    // Laravel 会自动解析定义在控制器方法（变量名匹配路由片段）中的 Eloquent 模型类型声明
    // show() 方法传参时声明了类型 —— Eloquent 模型 User，
    // 对应的变量名 $user 会匹配路由片段中的 {user}，
    // 这样，Laravel 会自动注入与请求 URI 中传入的 ID 对应的用户模型实例
    // 此功能称为 『隐性路由模型绑定』，是『约定优于配置』设计范式的体现，同时满足以下两种情况，此功能即会自动启用：
    // 1). 路由声明时必须使用 Eloquent 模型的单数小写格式来作为 路由片段参数，User 对应 {user}
    // 控制器方法传参中必须包含对应的 Eloquent 模型类型 提示，并且是有序的
    public function show(User $user)
    {
        // 将用户对象变量 $user 通过 compact 方法转化为一个关联数组，并作为第二个参数传递给 view 方法，将变量数据传递到视图中
        // show 方法添加完成之后，在视图中，我们即可直接使用 $user 变量来获取 view 方法传递给视图的用户数据
        return view('users.show', compact('user'));
    }

    public function edit(User $user)
    {
        /**
         * 这里 update 是指授权类里的 update 授权方法，
         * $user 对应传参 update 授权方法的第二个参数
         * 调用时，默认情况下，我们 不需要 传递第一个参数，
         * 也就是当前登录用户至该方法内，因为框架会 自动 加载当前登录用
         */
        $this->authorize('update', $user);
        return view('users.edit', compact('user'));
    }

    // update() 方法使用了『表单请求验证』（FormRequest）来验证用户提交的数据
    public function update(UserRequest $request, ImageUploadHandler $uploader, User $user)
    {
        $this->authorize('update', $user);
        $data = $request->all();

        if ($request->avatar) {
            $result = $uploader->save($request->avatar, 'avatars', $user->id, 416);
            if ($result) {
                $data['avatar'] = $result['path'];
            }
        }

        $user->update($data);
        return redirect()->route('users.show', $user->id)->with('success', '个人资料更新成功！');
    }
}
